Android Tips #36 PagerTabStrip を使って Google Play ストア風のアプリを作ってみる
PagerTabStrip とは
PagerTabStrip は ViewPager にタブ機能を追加するための View です。Support Package に含まれているので Android 1.6 (APIレベル4) から使用することができます。代表的な例として Google Play ストアアプリのアプリ一覧画面で使われています。
今回は PagerTabStrip を使ったサンプルとして Google Play ストアアプリを真似た下図のようなアプリを作ってみたので、その手順を解説したいと思います!
PagerTabStrip の使いかた
1. レイアウトを作る
まずはレイアウトを作ります。ViewPager にタブを表示するには、以下のように ViewPager に PagerTabStrip をネストします。これでタブを表示するための最低限の実装は完了したも同然です。簡単ですね!
activity_main.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v4.view.PagerTabStrip android:id="@+id/strip" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#333333" android:paddingBottom="6dp" android:paddingTop="6dp" /> </android.support.v4.view.ViewPager>
2. Fragment を作る
次に ViewPager で表示する画面を Fragment で作ります。今回は応用編ということで複数の Fragment を扱ってみたいと思います。
GridView の Fragment を作る
まずひとつめは GridView を表示する Fragment です。以下のクラスを作成しました(解説は割愛します)。GridView の作りかたはこちらを、Fragment の作りかたはこちらを参照してください。
データが加わると下図のように表示されます。
RelativeLayout の Fragment を作る
次にもうひとつ、 RelativeLayout の Fragment を作ります。データなどは入れずに、ただ ImageView を Google Play ストアの「おすすめページ」風にいくつか並べてみました。
3. FragmentPagerAdapter を実装する
次に PagerAdapter を実装します。今回はページに Fragment を使いたいと思うので FragmentPagerAdapter を使います。FragmentPagerAdapter の使いかたはこちらに掲載済みなので参照してください。応用編ということで、今回は複数の Fragment を取り扱ってみます。まずは以下のようなページ情報の DTO クラスをつくります。
PageItem.java
package jp.classmethod.android.sample.playstore; import java.util.ArrayList; /** * ページのアイテム. */ public class PageItem { /** GridView の Fragment の Id. */ public static final int GRID = 0; /** RelativeLayout の Fragment の Id. */ public static final int RELATIVE = 1; /** ページ名. */ public String title; /** Fragment の種類. */ public int fragmentKind; /** アプリケーションのリスト. */ public ArrayList<App> appList; }
次に FragmentPagerAdapter を実装します。タブにページの名前を表示するには getPageTitle() をオーバーライドします。ページ毎のデータは PageItem にまとめているので PageItem#title の値を返すようにします。また getItem() メソッド内では PageItem#fragmentKind をもとに返す Fragment を変えています。GridViewFragment を返す場合は Bundle に PageItem#appList をセットして setArguments() で渡すようにしています。
CustomFragmentPagerAdapter.java
package jp.classmethod.android.sample.playstore; import java.util.ArrayList; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; /** * FragmentPagerAdapter. */ public class CustomFragmentPagerAdapter extends FragmentPagerAdapter { /** {@link PageItem} のリスト. */ private ArrayList<PageItem> mList; /** * コンストラクタ. * @param fm {@link FragmentManager} */ public CustomFragmentPagerAdapter(FragmentManager fm) { super(fm); mList = new ArrayList<PageItem>(); } @Override public Fragment getItem(int position) { PageItem item = mList.get(position); if (PageItem.RELATIVE == item.fragmentKind) { // RelativeLayout の Fragment return new RecommendFragment(); } // GridView の Fragment GridViewFragment gridViewFragment = new GridViewFragment(); // Bundle を作成 Bundle bundle = new Bundle(); bundle.putSerializable("list", item.appList); gridViewFragment.setArguments(bundle); return gridViewFragment; } @Override public CharSequence getPageTitle(int position) { return mList.get(position).title; } @Override public int getCount() { return mList.size(); } /** * アイテムを追加する. * @param item {@link PageItem} */ public void addItem(PageItem item) { mList.add(item); } }
あとは Activity を実装して終わりです!オススメページ、人気アプリページ、新着アプリページを作ってみました。App のリストは (めんどうなので) 同じものを使いまわしていますが、本来であればそれぞれのリストを作って渡します。
MainActivity.java
package jp.classmethod.android.sample.playstore;
import java.util.ArrayList;
import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.util.TypedValue;
/** * ViewPager を表示する Activity. */ public class MainActivity extends FragmentActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
// PagerTitleStrip のカスタマイズ PagerTabStrip strip = (PagerTabStrip) findViewById(R.id.strip); strip.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); strip.setTextColor(0xff9acd32); strip.setTextSpacing(50); strip.setNonPrimaryAlpha(0.3f); strip.setDrawFullUnderline(true); strip.setTabIndicatorColor(0xff9acd32);
// ViewPager の Adapter CustomFragmentPagerAdapter adapter = new CustomFragmentPagerAdapter(getSupportFragmentManager());
// GridView の Adapter
ArrayList
実行すると以下のようになります!
サンプルソース
今回作成したアプリを github で公開しました。ぜひ参考にしてください!
PagerTabStrip のカスタマイズ
PagerTabStrip は文字色や文字サイズなどの表示をカスタマイズすることができます。以下にまとめてみました。
文字色を変更する
文字色の変更には PagerTabStrip#setTextColor() を使います。
文字サイズを変更する
文字サイズの変更には PagerTabStrip#setTextSize() を使います。第一引数には dp や sp といった単位の種類の定数クラス TypedValue から任意の定数を渡します。
非表示のページタイトルの透過度を変更する
非表示中(現在表示されているページの前後)のページタイトルの透過度を変更するには PagerTabStrip#setNonPrimaryAlpha() を使います。
ページタイトルの間隔を変更する
PagerTabStrip#setTextSpacing() でページタイトルとページタイトルの間隔を変更することができます。これは左にフリックしたときに前に表示していたページタイトルが新しいページタイトルに押し出される間隔になります。
ページタイトルの配置を変更する
ページタイトルの配置場所を PagerTabStrip#setGravity() で変更することができます。Vertical のみ有効になります。
ページタイトルのインジケータの色を変更する
インジケータとはページタイトルの下に表示されている太い線のことです。 PagerTabStrip#setTabIndicatorColor() で好きな色に変更できます。
下線の表示/非表示を変更する
PagerTabStrip#setDrawFullUnderline() で下線を表示するか否かを設定できます。
背景色を変更する
背景色を変更するには PagerTabStrip#setBackgroundColor() または PagerTabStrip#setBackgroundResource() を使います。
まとめ
PagerTabStrip 自体の実装は ViewPager にネストするだけなのでとても簡単です!あとは表示を少しカスタマイズできるところが良いですね〜。何より Android 1.6 から利用できるところが素敵です。画面を分割するために ViewPager を使おうとしているケースで特に重宝すると思います。ぜひ使ってみてください。また PagerTabStrip をもっとシンプルにしたい場合は親クラスである PagerTitleStrip があるのでそちらの使用も検討してみても良いと思います。